

import GameInputEvent from "./GameInputEvent";
import { CtrlModeListener, KeyEventListener, MouseEventListener, RockerEventListener } from "./GameInputListeners";
import { InputKeyCode, InputType, InputTypeTip, KeyEventType } from "./InputConfig";
import InputConverter from "./InputConverter";
import InputListenerMgr from "./InputListenerMgr";
/**
 * 游戏键鼠，手柄转换器 
 */

export default class GameInputMgr {

    private static ins: GameInputMgr;

    static instance() {
        if (!this.ins) {
            this.ins = new GameInputMgr()
        }
        return this.ins;
    }


    protected singleKeyEvents: GameInputEvent[] = []
    protected mutiyKeyEvent: GameInputEvent = new GameInputEvent();
    protected mouseEvent: GameInputEvent = new GameInputEvent();
    protected rockerEvent: GameInputEvent = new GameInputEvent();
    protected _converter: InputConverter = new InputConverter();


    //按键监听队列
    protected keyList: InputListenerMgr<KeyEventListener> = new InputListenerMgr();

    //任意按键监听队列
    protected anyKeyList: InputListenerMgr<KeyEventListener> = new InputListenerMgr();
    //鼠标监听队列
    protected mouseList: InputListenerMgr<MouseEventListener> = new InputListenerMgr();
    //遥感监听队列
    protected rockerList: InputListenerMgr<RockerEventListener> = new InputListenerMgr();
    //多按键监听队列
    // protected multyListener: InputListenerMgr<MultiKeyListener> = new InputListenerMgr();
    //键盘鼠标切换状态监听队列
    protected listeners: InputListenerMgr<CtrlModeListener> = new InputListenerMgr();


    getSingleKeyEvent(keyCode: InputKeyCode) {
        let e = this.singleKeyEvents[keyCode]
        if (!e) {
            e = new GameInputEvent()
            this.singleKeyEvents[keyCode] = e;
        }
        return e;
    }

    //当前平台类型
    protected _type: string = InputType.CC;

    get type() {
        return this._type;
    }

    //是否是手柄
    isHandle() {
        return this.type == InputType.STEAM
    }

    isKeyboard() {
        return this.type == InputType.CC;
    }

    changeType(t: string) {
        if (this.type != t) {
            this.type = t;
        }
    }

    set type(t: string) {
        this._type = t;
        let list = this.listeners.list
        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onChangeMode(this._type)
        }
    }
    /**
     * 添加模式切换事件监听对象
     * @param listener 监听对象
    */
    public addCtrlModeListener(listener: CtrlModeListener) {
        this.listeners.on(listener)
    }

    /**
     * 删除模式切换事件监听对象
     * @param listener 监听对象
    */
    public removeCtrlModeListener(listener: CtrlModeListener) {
        this.listeners.off(listener)
    }

    getCfgName() {
        return InputTypeTip[this.type]// + '_key'
    }


    /**
     * 根据按键名称获取按键图标
     * @param keyName 按键名称
     * @returns 
     */
    getKeyCodeImg(keyName: string, group?: number) {
        let imgKey = this.getCfgName();
        return this.converter.getKeyImg(keyName, imgKey, group);
    }

    /**
     * 根据键值获得按键图标
     * @param value 键值
     * @returns 
     */
    getKeyCodeImgByKeyValue(value: InputKeyCode, group?: number) {
        let keyCode = this.converter.getKeyName(value, group)
        return this.getKeyCodeImg(keyCode, group)
    }

    get converter() {
        return this._converter;
    }



    getKeyEvent() {
        return this.mutiyKeyEvent;
    }



    addKeyEventListener(listener: KeyEventListener) {
        this.keyList.on(listener)
    }

    removeKeyEventListener(listener: KeyEventListener) {
        this.keyList.off(listener)
    }

    addAnyKeyEventListener(listener: KeyEventListener) {
        this.anyKeyList.on(listener)
    }

    removeAnyKeyEventListener(listener: KeyEventListener) {
        this.anyKeyList.off(listener)
    }

    // addMouseEventListener(listener: MouseEventListener) {
    //     this.mouseList.on(listener)
    // }

    // removeMouseEventListener(listener: MouseEventListener) {
    //     this.mouseList.off(listener)
    // }

    addRockerEventListener(listener: RockerEventListener) {
        this.rockerList.on(listener)
    }

    removeRockerEventListener(listener: RockerEventListener) {
        this.rockerList.off(listener)
    }

    onKeyBoardPress(platform: string, keyCode: number, pos: any) {
        keyCode = this.converter.getKeyValue(platform, keyCode)
        if (!keyCode) {
            console.log(' key is undefined group is ', this.converter.getGroup())
            return;
        }


        let singleKeyEvent = this.getSingleKeyEvent(keyCode)

        singleKeyEvent.keyCode = keyCode;
        singleKeyEvent.pos = pos;

        console.log('onKeyBoardPress keyCode  ', keyCode, this.converter.getKeyName(keyCode))
        this.mutiyKeyEvent.keyCode |= keyCode;
        this.mutiyKeyEvent.pos = pos;

        let anyList = this.anyKeyList.list;
        for (let index = anyList.length - 1; index >= 0; index--) {
            const element = anyList[index];
            element.onKeyBoardPress(keyCode, singleKeyEvent)
        }

        let list = this.keyList.list;
        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onKeyBoardPress(keyCode, singleKeyEvent)
            if (element.isBlockInput()) {
                break;
            }
        }

    }

    onKeyBoardRelease(platform: string, keyCode: number, pos: any) {
        keyCode = this.converter.getKeyValue(platform, keyCode)
        if (!keyCode) {
            console.log(' key is undefined ')
            return;
        }

        this.mutiyKeyEvent.keyCode &= ~keyCode;
        this.mutiyKeyEvent.pos = pos;
        let singleKeyEvent = this.getSingleKeyEvent(keyCode)

        singleKeyEvent.keyCode = keyCode;
        singleKeyEvent.pos = pos;


        let anyList = this.anyKeyList.list;
        for (let index = anyList.length - 1; index >= 0; index--) {
            const element = anyList[index];
            element.onKeyBoardPress(keyCode, singleKeyEvent)
        }

        let list = this.keyList.list;
        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onKeyBoardRelease(keyCode, singleKeyEvent)
            if (element.isBlockInput()) {
                break;
            }
        }

    }
    onMouseMove(platform: string, keyCode: number, pos: any): void {
        keyCode = this.converter.getKeyValue(platform, keyCode)
        // if (!keyCode) {
        //     return;
        // }
        let list = this.mouseList.list;
        this.mouseEvent.keyCode = keyCode;
        this.mouseEvent.pos = pos;

        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onMouseMove(keyCode, this.mouseEvent)
            if (element.isBlockMouse()) {
                break;
            }
        }
    }

    onMouseDown(platform: string, keyCode: number, pos: any): void {
        keyCode = this.converter.getKeyValue(platform, keyCode)
        if (!keyCode) {
            return;
        }
        this.mouseEvent.keyCode = keyCode;
        this.mouseEvent.pos = pos;
        // console.log('onMouseDown keyCode  ', keyCode)
        let list = this.mouseList.list;
        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onMouseDown(keyCode, this.mouseEvent)
            if (element.isBlockMouse()) {
                break;
            }
        }
    }

    onMouseUp(platform: string, keyCode: number, pos: any): void {
        keyCode = this.converter.getKeyValue(platform, keyCode)
        if (!keyCode) {
            return;
        }
        this.mouseEvent.keyCode = keyCode;
        this.mouseEvent.pos = pos;
        // console.log('onMouseUp keyCode  ', keyCode)
        let list = this.mouseList.list;
        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onMouseUp(keyCode, this.mouseEvent)
            if (element.isBlockMouse()) {
                break;
            }
        }
    }


    onRockerEvent(platform: string, keyCode: number, x: number, y: number): void {
        keyCode = this.converter.getKeyValue(platform, keyCode)
        if (!keyCode) {
            return;
        }
        let list = this.rockerList.list;
        this.rockerEvent.keyCode = keyCode;
        this.rockerEvent.pos.set(x, y)
        for (let index = list.length - 1; index >= 0; index--) {
            const element = list[index];
            element.onRockerEvent(keyCode, this.rockerEvent)
            if (element.isBlockRocker()) {
                break;
            }
        }
    }
}